home *** CD-ROM | disk | FTP | other *** search
/ 3D GFX / 3D GFX.iso / amiutils / i_l / irit5 / cagd_lib / cagdbsum.c < prev    next >
C/C++ Source or Header  |  1995-12-30  |  8KB  |  191 lines

  1. /******************************************************************************
  2. * CagdBSum.c - Boolean sum surface constructor out of given four curves.      *
  3. *******************************************************************************
  4. * Written by Gershon Elber, Sep. 91.                          *
  5. ******************************************************************************/
  6.  
  7. #include "cagd_loc.h"
  8.  
  9. /*****************************************************************************
  10. * DESCRIPTION:                                                               M
  11. * Constructs a Boolean sum surface using the four provided boundary curves.  M
  12. *   Curve's end points must meet at the four surface corners if surface      M
  13. * boundary are to be identical to the four given curves.                 M
  14. *                                                                            *
  15. * PARAMETERS:                                                                M
  16. *   CrvLeft:    Left boundary curve of Boolean sum surface to be created.    M
  17. *   CrvRight:   Right boundary curve of Boolean sum surface to be created.   M
  18. *   CrvTop:     Top boundary curve of Boolean sum surface to be created.     M
  19. *   CrvBottom:  Bottom boundary curve of Boolean sum surface to be created.  M
  20. *                                                                            *
  21. * RETURN VALUE:                                                              M
  22. *   CagdSrfStruct *:  A Boolean sum surface constructed using given four     M
  23. *                     curves.                                                M
  24. *                                                                            *
  25. * KEYWORDS:                                                                  M
  26. *   CagdBoolSumSrf, Boolean sum, surface constructors                        M
  27. *****************************************************************************/
  28. CagdSrfStruct *CagdBoolSumSrf(CagdCrvStruct *CrvLeft,
  29.                   CagdCrvStruct *CrvRight,
  30.                   CagdCrvStruct *CrvTop,
  31.                   CagdCrvStruct *CrvBottom)
  32. {
  33.     int i, j;
  34.     CagdCrvStruct *Crv1, *Crv2;
  35.     CagdSrfStruct *Ruled1, *Ruled2, *Ruled3, *Srf;
  36.     CagdPtStruct Pt1, Pt2;
  37.     CagdRType **SrfPoints, **Ruled1Pts, **Ruled2Pts, **Ruled3Pts;
  38.  
  39.     if (CAGD_IS_PERIODIC_CRV(CrvLeft) ||
  40.     CAGD_IS_PERIODIC_CRV(CrvRight) ||
  41.     CAGD_IS_PERIODIC_CRV(CrvTop) ||
  42.     CAGD_IS_PERIODIC_CRV(CrvBottom)) {
  43.     CAGD_FATAL_ERROR(CAGD_ERR_PERIODIC_NO_SUPPORT);
  44.     return NULL;
  45.     }
  46.  
  47.     CrvLeft = CagdCrvCopy(CrvLeft);
  48.     CrvRight = CagdCrvCopy(CrvRight);
  49.     CrvTop = CagdCrvCopy(CrvTop);
  50.     CrvBottom = CagdCrvCopy(CrvBottom);
  51.  
  52.     /* The Left-Right and Top-Bottom curves should share same point/curve    */
  53.     /* type as well as same order and knot vector (if Bspline representation)*/
  54.     CagdMakeCrvsCompatible(&CrvLeft, &CrvRight, TRUE, TRUE);
  55.     CagdMakeCrvsCompatible(&CrvTop, &CrvBottom, TRUE, TRUE);
  56.  
  57.     /* The Left-Right and Top-Bottom pairs must share same point/curve type. */
  58.     CagdMakeCrvsCompatible(&CrvLeft, &CrvTop, FALSE, FALSE);
  59.     CagdMakeCrvsCompatible(&CrvLeft, &CrvBottom, FALSE, FALSE);
  60.     CagdMakeCrvsCompatible(&CrvRight, &CrvTop, FALSE, FALSE);
  61.     CagdMakeCrvsCompatible(&CrvRight, &CrvBottom, FALSE, FALSE);
  62.  
  63.     /* Now that the curves are in the right representation, form surface(s). */
  64.     /* The two ruled surface between the respective curves, in right orders: */
  65.     Ruled1 = CagdRuledSrf(CrvLeft, CrvRight,
  66.               CrvTop -> Order, CrvTop -> Length);
  67.     Ruled2 = CagdRuledSrf(CrvTop, CrvBottom,
  68.               CrvRight -> Order, CrvRight -> Length);
  69.     Srf = CagdSrfReverse2(Ruled2);
  70.     CagdSrfFree(Ruled2);
  71.     Ruled2 = Srf;
  72.  
  73.     /* The ruled surface between the four corner points in the right orders. */
  74.     CagdCoerceToE3(Pt1.Pt, CrvLeft -> Points, 0, CrvLeft -> PType);
  75.     CagdCoerceToE3(Pt2.Pt, CrvLeft -> Points, CrvLeft -> Length - 1,
  76.                             CrvLeft -> PType);
  77.     Crv1 = CagdMergePtPt(&Pt1, &Pt2);
  78.  
  79.     CagdCoerceToE3(Pt1.Pt, CrvRight -> Points, 0, CrvRight -> PType);
  80.     CagdCoerceToE3(Pt2.Pt, CrvRight -> Points, CrvRight -> Length - 1,
  81.                             CrvRight -> PType);
  82.     Crv2 = CagdMergePtPt(&Pt1, &Pt2);
  83.  
  84.     /* Should not change CrvLeft/Right only Crv1/2: */
  85.     CagdMakeCrvsCompatible(&Crv1, &CrvLeft, TRUE, TRUE);
  86.     CagdMakeCrvsCompatible(&Crv2, &CrvRight, TRUE, TRUE);
  87.  
  88.     Ruled3 = CagdRuledSrf(Crv1, Crv2, CrvTop -> Order, CrvTop -> Length);
  89.     CagdCrvFree(Crv1);
  90.     CagdCrvFree(Crv2);
  91.  
  92.     /* The boolean sum is equal to Ruled1 + Ruled2 - Ruled3. This boolean    */
  93.     /* sum as computed is not exactly as defined in the literature for non   */
  94.     /* uniform Bsplines since the ruled surfaces are computed with uniform   */
  95.     /* distribution along the other axis even if it is non uniform.         */
  96.     if (CrvRight -> GType == CAGD_CBSPLINE_TYPE) {
  97.     Srf = BspSrfNew(Ruled1 -> ULength, Ruled1 -> VLength,
  98.             Ruled1 -> UOrder, Ruled1 -> VOrder, Ruled1 -> PType);
  99.     IritFree((VoidPtr) Srf -> UKnotVector);
  100.     Srf -> UKnotVector = BspKnotCopy(CrvLeft -> KnotVector,
  101.                      CrvLeft -> Length + CrvLeft -> Order);
  102.     IritFree((VoidPtr) Srf -> VKnotVector);
  103.     Srf -> VKnotVector = BspKnotCopy(CrvTop -> KnotVector,
  104.                      CrvTop -> Length + CrvTop -> Order);
  105.     }
  106.     else if (CrvRight -> GType == CAGD_CBEZIER_TYPE)
  107.     Srf = BzrSrfNew(Ruled1 -> ULength, Ruled1 -> VLength, Ruled1 -> PType);
  108.     else
  109.     CAGD_FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  110.     SrfPoints = Srf -> Points;
  111.  
  112.     Ruled1Pts = Ruled1 -> Points;
  113.     Ruled2Pts = Ruled2 -> Points;
  114.     Ruled3Pts = Ruled3 -> Points;
  115.  
  116.     for (i = !CAGD_IS_RATIONAL_SRF(Srf);
  117.      i <= CAGD_NUM_OF_PT_COORD(Srf -> PType);
  118.      i++) {
  119.     CagdRType
  120.         *Ruled1PtsPtr = Ruled1Pts[i],
  121.         *Ruled2PtsPtr = Ruled2Pts[i],
  122.         *Ruled3PtsPtr = Ruled3Pts[i],
  123.         *SrfPointsPtr = SrfPoints[i];
  124.  
  125.      for (j = Srf -> ULength * Srf -> VLength; j > 0; j--)
  126.          *SrfPointsPtr++ =
  127.          *Ruled1PtsPtr++ + *Ruled2PtsPtr++ - *Ruled3PtsPtr++;
  128.     }
  129.  
  130.     CagdSrfFree(Ruled1);
  131.     CagdSrfFree(Ruled2);
  132.     CagdSrfFree(Ruled3);
  133.  
  134.     return Srf;
  135. }
  136.  
  137. /*****************************************************************************
  138. * DESCRIPTION:                                                               M
  139. * Constructs a Boolean sum surface using the single boundary curve.         M
  140. *   The curve is subdivided into four, equally spaced in parameter space,    M
  141. * sub-regions which are used as the four curves to the Boolean sum           M
  142. * constructor. See CagdBoolSumSrf.                                           M
  143. *                                                                            *
  144. * PARAMETERS:                                                                M
  145. *   BndryCrv:   To be subdivided into four curves for a Boolean sum          M
  146. *               construction.                                                M
  147. *                                                                            *
  148. * RETURN VALUE:                                                              M
  149. *   CagdSrfStruct *:  A Boolean sum surface constructed using given curve    M
  150. *                                                                            *
  151. * KEYWORDS:                                                                  M
  152. *   CagdBoolSumSrf, Boolean sum, surface constructors                        M
  153. *****************************************************************************/
  154. CagdSrfStruct *CagdOneBoolSumSrf(CagdCrvStruct *BndryCrv)
  155. {
  156.     CagdRType TMin, TMax;
  157.     CagdCrvStruct *Crvs, *TCrv, *CrvLeft, *CrvRight, *CrvTop, *CrvBottom;
  158.     CagdSrfStruct *BoolSumSrf;
  159.  
  160.     BspCrvDomain(BndryCrv, &TMin, &TMax);
  161.  
  162.     Crvs = BspCrvSubdivAtParam(BndryCrv, TMin * 0.5 + TMax * 0.5);
  163.     CrvLeft = BspCrvSubdivAtParam(Crvs, TMin * 0.75 + TMax * 0.25);
  164.     CrvRight = BspCrvSubdivAtParam(Crvs -> Pnext, TMin * 0.25 + TMax * 0.75);
  165.  
  166.     CagdCrvFreeList(Crvs);
  167.  
  168.     CrvBottom = CrvLeft -> Pnext;
  169.     CrvLeft -> Pnext = NULL;
  170.     CrvTop = CrvRight -> Pnext;
  171.     CrvRight -> Pnext = NULL;
  172.  
  173.     /* Reverse CrvBottom and CrvLeft: */
  174.     TCrv = CagdCrvReverse(CrvTop);
  175.     CagdCrvFree(CrvTop);
  176.     CrvTop = TCrv;
  177.  
  178.     TCrv = CagdCrvReverse(CrvRight);
  179.     CagdCrvFree(CrvRight);
  180.     CrvRight = TCrv;
  181.  
  182.     BoolSumSrf = CagdBoolSumSrf(CrvLeft, CrvRight, CrvTop, CrvBottom);
  183.  
  184.     CagdCrvFree(CrvTop);
  185.     CagdCrvFree(CrvRight);
  186.     CagdCrvFree(CrvBottom);
  187.     CagdCrvFree(CrvLeft);
  188.  
  189.     return BoolSumSrf;
  190. }
  191.